//@author A0083782W
#include "EventStorage.h"

string const EventStorage::fileName = "D:\\TEDataFile.txt";
bool EventStorage::hasRun = false; 

EventStorage::EventStorage() {
	readFile();
}

EventStorage::~EventStorage() {
	saveFile();
}

void EventStorage::writeTimeToFile (const Time& timer, fstream& fp) const{
	for (pos_int i = Time::FIRST_MEMBER; i < Time::TIME_MAX - 1; i++) {
		fp << (pos_int)timer.getTime((TimeType)i) << endl;
	}
	fp << (int)timer.isSecondDisplayable() << endl;
}

Time EventStorage::readTimeFromFile (fstream& fp) {
	Time timer;
	string fileInput;
	for (pos_int i = Time::FIRST_MEMBER; i < Time::TIME_MAX - 1; i++) {
		getline (fp, fileInput);
		timer.setTime ((TimeType)i, atoi(fileInput.c_str()));
	}
	getline (fp, fileInput);
	timer.setSecondDisplay ( atoi(fileInput.c_str()) != 0);
	return timer;
}
	
void EventStorage::writeEventToFile (Event& theEvent, fstream& fp) const{
	fp << theEvent.getDetails() << endl;;
	writeTimeToFile (theEvent.getStartTime(), fp);
	writeTimeToFile (theEvent.getEndTime(), fp);
	fp << (pos_int)theEvent.isDuration() << endl;
	writeTimeToFile (theEvent.getRemindTime(), fp);
	fp << (pos_int) theEvent.getRepeatRule().frequency << endl;
	fp << theEvent.getRepeatRule().period << endl;
	fp << (pos_int) theEvent.getRepeatRule().startOfWeek << endl;

	vector<string>* readTags = theEvent.getTagPtr();
	fp << readTags->size() << endl;
	for (auto i:*readTags) {
		fp << i << endl;
	}
	fp << theEvent.isDone() << endl;
	fp << theEvent.isReminded() << endl;
	fp << theEvent.isMissed() << endl;
	fp << theEvent.isFavourite() << endl;
}

Event EventStorage::readEventFromFile (fstream& fp) {
	Event newEvent;
	Time timer;
	REPEAT_RULE tempRule;
	string fileInput;
	pos_int tagSize;
	vector<string>* stringPtr;

	getline (fp, fileInput);
	newEvent.setDetails (fileInput);
	timer = readTimeFromFile(fp);
	newEvent.setStartTime (timer);
	timer = readTimeFromFile(fp);
	newEvent.setEndTime (timer);
	getline (fp,fileInput);
	newEvent.setDurationType (atoi (fileInput.c_str ()) != 0);
	timer = readTimeFromFile(fp);
	newEvent.setRemindTime (timer);
	getline (fp, fileInput);
	tempRule.frequency = (RepeatFrequency) atoi (fileInput.c_str());
	getline (fp, fileInput);
	tempRule.period = atoi (fileInput.c_str());
	getline (fp, fileInput);
	tempRule.startOfWeek = (WeekDay) atoi (fileInput.c_str());
	newEvent.setRepeatRule (tempRule);
	stringPtr = newEvent.getTagPtr();
	getline (fp, fileInput);
	tagSize = atoi (fileInput.c_str());
	for (pos_int i = 0; i < tagSize; i++) {
		getline (fp, fileInput);
		stringPtr->push_back (fileInput);
	}
	getline (fp, fileInput);
	newEvent.setDone ( atoi (fileInput.c_str()) != 0);
	getline (fp, fileInput);
	newEvent.setReminded ( atoi (fileInput.c_str()) != 0);
	getline (fp, fileInput);
	newEvent.setMissed ( atoi (fileInput.c_str()) != 0);
	getline (fp, fileInput);
	newEvent.setFavourite ( atoi (fileInput.c_str()) != 0);
	return newEvent;
}

EventStorage& EventStorage::get() {
	static EventStorage firstInstance;
	if (hasRun ==  false) {
		//first run
		hasRun = true;
	}
	
	return firstInstance;
}

EventVector* EventStorage::getEventVectorPtr() {
	return &_eventData;
}

Time EventStorage::getStartDay() {
	return _startDay;
}

void EventStorage::readFile() {
	fstream filePtr;
	string fileInput;
	pos_int vectorSize = 0;
	filePtr.open (fileName);
	_startDay = readTimeFromFile (filePtr);
	getline (filePtr, fileInput);
	if ( isNumString(fileInput) == false) {
		filePtr.close();
		return;
	}	
	vectorSize = atoi (fileInput.c_str());
	for (pos_int i = 0; i < vectorSize; i++) {
		Event newEvent;
		newEvent = readEventFromFile(filePtr);
		_eventData.push_back (newEvent);
	}
	filePtr.close();
}

void EventStorage::saveFile() {
	fstream filePtr;
	filePtr.open (fileName, ios::trunc|ios::out);
	CurrentTime nowClock;
	Time newClock;
	newClock  = nowClock;
	writeTimeToFile(newClock, filePtr);
	filePtr << _eventData.size() << endl;
	if (_eventData.size() > 0) {
		for (pos_int i = 0; i < _eventData.size(); i++) {
			writeEventToFile (_eventData[i], filePtr);
		}
	}
	filePtr.close();
}
